{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":44567,"sourceType":"datasetVersion","datasetId":10449}],"dockerImageVersionId":30840,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<font color=\"red\">注</font>: 使用 tensorboard 可视化需要安装 tensorflow (TensorBoard依赖于tensorflow库，可以任意安装tensorflow的gpu/cpu版本)\n\n```shell\npip install tensorflow-cpu\n```","metadata":{},"attachments":{}},{"cell_type":"code","source":"import matplotlib as mpl\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport numpy as np\nimport sklearn\nimport pandas as pd\nimport os\nimport sys\nimport time\nfrom tqdm.auto import tqdm\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nprint(sys.version_info)\nfor module in mpl, np, pd, sklearn, torch:\n    print(module.__name__, module.__version__)\n    \ndevice = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\nprint(device)\n\nseed = 42\n","metadata":{"ExecuteTime":{"end_time":"2025-01-20T03:13:43.991929Z","start_time":"2025-01-20T03:13:41.654523Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:29.422043Z","iopub.execute_input":"2025-01-20T06:36:29.422375Z","iopub.status.idle":"2025-01-20T06:36:29.433336Z","shell.execute_reply.started":"2025-01-20T06:36:29.422349Z","shell.execute_reply":"2025-01-20T06:36:29.432067Z"}},"outputs":[{"name":"stdout","text":"sys.version_info(major=3, minor=10, micro=12, releaselevel='final', serial=0)\nmatplotlib 3.7.5\nnumpy 1.26.4\npandas 2.2.2\nsklearn 1.2.2\ntorch 2.5.1+cu121\ncuda:0\n","output_type":"stream"}],"execution_count":11},{"cell_type":"markdown","source":"## 数据准备\n\n```shell\n$ tree -L 2 archive \narchive\n├── monkey_labels.txt\n├── training\n│   ├── n0\n│   ├── n1\n│   ├── n2\n│   ├── n3\n│   ├── n4\n│   ├── n5\n│   ├── n6\n│   ├── n7\n│   ├── n8\n│   └── n9\n└── validation\n    ├── n0\n    ├── n1\n    ├── n2\n    ├── n3\n    ├── n4\n    ├── n5\n    ├── n6\n    ├── n7\n    ├── n8\n    └── n9\n\n22 directories, 1 file\n```","metadata":{},"attachments":{}},{"cell_type":"code","source":"!mount","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:29.434702Z","iopub.execute_input":"2025-01-20T06:36:29.435006Z","iopub.status.idle":"2025-01-20T06:36:29.588493Z","shell.execute_reply.started":"2025-01-20T06:36:29.434940Z","shell.execute_reply":"2025-01-20T06:36:29.587603Z"}},"outputs":[{"name":"stdout","text":"overlay on / type overlay (rw,relatime,lowerdir=l/LAMH4CKVK7ZUZM6PQ2QDRGPDIT:l/2G2JDGCUOSGKNUCAMLQO2N6XAV:l/IXTVHKMTI6JS7WVIJOVO7B5DMU:l/5JEMZB5XK7ZOZ2APFZ5HOM7Y2C:l/R7J2S3RZLK6V5D2DU22F2APTEM:l/3DVQ6CHOH2HBOPPHGUZQ4UOHFF:l/MFA4T6TZLSRROOFY5XFFMYSTWM:l/SBBL56DIUGJL4LKYKR5H3JMJOS:l/NPOOK6M74ZCIZ5ZJH5JNEEEU4G:l/7VKXOZXVXEMX2RLBLYJAGQAL4V:l/IQTZLKNK4P5P7ICQJJCWVOZAVN:l/4OYYHBTQYOIRDU5NY6LZLNVY55:l/EFUQEB4QYWK6DWOLYVR7VSPUNW:l/B3FRFDT3PHZISTXJ6NINNYCDQG:l/TVZMLF67A5PWGTFFGVPGF5PVS2:l/2UO725QTXZ6IKNQIMGQYOKC5SH:l/AAF3QR4NUBP4CLX5TXLYHC5ANK:l/IPPF2K52EIL5UBPIVZ7QGAGCMJ:l/2NTROW3NLWY7GRR3Y6SZHL4AOE:l/DYPBF7C53K5GVQR4VG6DWWLDNT:l/BYFMSQPEGVSV5BTZITYNNLTYZU:l/S4RW4K7LNNWYU2JE2SDQJKLPTJ:l/ET6SADCEFWV3VZX736X3WCNF2U:l/K352WL6RKLX2BQO5PODNEQZAA5:l/XFNZUOMQ3SASDGAFV6ETBDL7Y3:l/PCCPWNYII6B2J5NWU5QAHUKHRS:l/JWN57FGMEHGXWONOP26PN2PSYH:l/GTTTHWNQ56U3LOORDKTHXNVHJY:l/5OOJY7I24FIGAI24YH4VSKM4LU:l/N4ZNUK7OMCF2WERC3WBRFZOVIT:l/ZBHRQL57TVFXN65DXOIXFSS3NT:l/7L6PXUQ4JF53ACXPIXAEGB3UON:l/SPT2ZUD7NTUTUYFNX7XNVXM6YO:l/OUW6EOTB6JSKPDAR3MHQIMBTQU:l/EAG3DQBTH2RZJU56RPS2DMW3FZ:l/W2V43AIPCYOMGPSIDHYQRKK4W5:l/IK2ERFMHXYCEGHTGJT4BVGTOYT:l/25PZ2ZKEYY3IROETZ2EFXJHPK3:l/RNTSK63K2RGUC6EOUBSGIXD4KY:l/QVZK3MX77IXEOOAWN6VS4F2EW4:l/JDJFQBTIZPYCWRQKHMYYBQ7ORD:l/H6XKQ3LMRC5TB2TGKUF5FVQDFL:l/GE5G5GA72UZ3QSCIXUSW72PWWP:l/I5AZ6SVGRIAWYQ4CJXX6IXGM6X:l/JFR6XFVGAS2LJTG5G2IGVG7PLE:l/JDSE5OEWFE5ATGKJLYUD2EJSIU:l/KLXLE2AFDXXFSV7KFO3UIHAWOF:l/IPOALIAKJWVQTJL3O2RZPEBPNU:l/7JTY243YUZYEDS4X3IIYCR74RN:l/VCEPXYHFP7NW55Q3WPE4NDQO5A:l/ELNX7366LMFHPL5K4LMHKMUTLM:l/DADX75RMFUY2UCDUUNZ4DRO7PF:l/3TNYU2WNVTZGJ333Y77SWBJLH5:l/ZNEHFG3JZEPAUNBF7ON6OELJRS:l/SHJ5J5H4NWHHIA6KMOQ7HSKUNH:l/RZ3KZJTWFLIB5HYAPAMAKPHURM:l/DHDX2MDBRELRID3RU4YIYYHSXN:l/IH33RKX37OFGW3VQQPMJXZ4LQY:l/URWLQUHDDDFKFA2UA6CMOPXJT4:l/OGGQ4ERCLFAHEIRCJJPIY2ZESL:l/SEOQMSZ3EBNBANDH4OOV32RZP7:l/5W7LCVUAI4JMSXKU5NAYZINXQM:l/IEDT7Q3T2MIGBJ2HBSGZVP4ZAQ:l/VNYN4GPYW4VDDOVFWX4YGICGNC:l/RAEKJNOCIB2OE2XUW6KQ5PH7SZ:l/VQSFA7VXWTJ5ZHFCVISSPRWTZA:l/HYHR4KQSJTNI5CJ2H64PAO5WNT:l/ZISREW3JFDPU5HEUPLPB3AVO55:l/BS7YRVUILYVI4BJIPGXYZJUL5D:l/XTQOMS36IRF7NVX5UMXQCWV2CK:l/6HH5S4ASYGNJFF2IZUKVG5ZBAF:l/NBBJDHFB7PGCAYGQ7CR4SKVSE5:l/RP4TNMZ3C5ZYJFJMBJOUW426L4:l/7LMPLJO76OHI2EV3DCWLOGCZLD:l/WCU4HNBA7JIUJX66ZI5UTG6SJL:l/K62PWBZ3S56FF2DO23OH2UJYBM:l/N5J6XWIJIU3GKS3ONO225FKEQI:l/7UCSMR7HDFKBDIOMRAVQFW6O4P:l/MQNJEGWF3V5NGCSUXAOGXTMZD4:l/BHVSNXRY3XSICGWGVRCC4X7JHO:l/RC3BEI67TXMEXGYSUX2XRMYZUU:l/M5YGGXVSWMIZZJFLLSBP7TA57D:l/DQUNGIY5A4OOX6E5V4CKD6DDOB:l/CIJCRUQQP26D7TDMXTE4G6XM3C:l/S3M55WUIS6OZCMKFWJJC6Z6PRD:l/C3NPER3EVA34LXZHEDRCDV6DMJ,upperdir=523b5b0240a064e53afbabcce2612b54d3a338b980fdfecab57fea65d00895cd/diff,workdir=523b5b0240a064e53afbabcce2612b54d3a338b980fdfecab57fea65d00895cd/work)\nproc on /proc type proc (rw,nosuid,nodev,noexec,relatime)\ntmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)\ndevpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)\nsysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)\ncgroup on /sys/fs/cgroup type cgroup2 (ro,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)\nmqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)\nshm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=14155776k)\n/tmp/fs/kaggle_qW0V1yLta7gEieZKhg8dqCrBuyJjFc4flWDMiqHCEEM-218400139-webtier/srcfile on /kaggle/input type ext4 (ro,relatime)\n192.168.7.2:/data/kagglesdsdata/datasets/10449/44567/d76oteh9syy4 on /kaggle/input/10-monkey-species type nfs (ro,relatime,vers=3,rsize=524288,wsize=1048576,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.7.2,mountvers=3,mountport=2050,mountproto=tcp,local_lock=all,addr=192.168.7.2)\n/dev/sda1 on /opt/bin type ext4 (ro,relatime,commit=30)\n/tmp/fs/kaggle_qW0V1yLta7gEieZKhg8dqCrBuyJjFc4flWDMiqHCEEM-218400139-webtier/srcfile on /kaggle/working type ext4 (rw,relatime)\n/tmp/fs/kaggle_qW0V1yLta7gEieZKhg8dqCrBuyJjFc4flWDMiqHCEEM-218400139-webtier/srcfile on /kaggle/lib type ext4 (ro,relatime)\n/dev/mapper/snap on /etc/resolv.conf type ext4 (rw,relatime)\n/dev/mapper/snap on /etc/hostname type ext4 (rw,relatime)\n/dev/mapper/snap on /etc/hosts type ext4 (rw,relatime)\n/tmp/fs/kaggle_qW0V1yLta7gEieZKhg8dqCrBuyJjFc4flWDMiqHCEEM-218400139-webtier/srcfile on /etc/secrets/kaggle type ext4 (ro,relatime)\n/dev/sda1 on /usr/local/nvidia/lib64 type ext4 (ro,relatime,commit=30)\n/dev/sda1 on /usr/local/cuda-12.2/targets/x86_64-linux/lib/stubs type ext4 (ro,relatime,commit=30)\nproc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime)\nproc on /proc/fs type proc (ro,nosuid,nodev,noexec,relatime)\nproc on /proc/irq type proc (ro,nosuid,nodev,noexec,relatime)\nproc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime)\nproc on /proc/sysrq-trigger type proc (ro,nosuid,nodev,noexec,relatime)\ntmpfs on /proc/acpi type tmpfs (ro,relatime)\ntmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755)\ntmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755)\ntmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755)\ntmpfs on /proc/scsi type tmpfs (ro,relatime)\ntmpfs on /sys/firmware type tmpfs (ro,relatime)\n","output_type":"stream"}],"execution_count":12},{"cell_type":"code","source":"!tree archive ","metadata":{"ExecuteTime":{"end_time":"2025-01-20T03:17:25.523601Z","start_time":"2025-01-20T03:17:25.494520Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:29.590577Z","iopub.execute_input":"2025-01-20T06:36:29.590820Z","iopub.status.idle":"2025-01-20T06:36:29.720776Z","shell.execute_reply.started":"2025-01-20T06:36:29.590799Z","shell.execute_reply":"2025-01-20T06:36:29.719446Z"}},"outputs":[{"name":"stdout","text":"/bin/bash: line 1: tree: command not found\n","output_type":"stream"}],"execution_count":13},{"cell_type":"code","source":"!ls /kaggle/input/10-monkey-species/training/training","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:29.723034Z","iopub.execute_input":"2025-01-20T06:36:29.723458Z","iopub.status.idle":"2025-01-20T06:36:29.857847Z","shell.execute_reply.started":"2025-01-20T06:36:29.723414Z","shell.execute_reply":"2025-01-20T06:36:29.857004Z"}},"outputs":[{"name":"stdout","text":"n0  n1\tn2  n3\tn4  n5\tn6  n7\tn8  n9\n","output_type":"stream"}],"execution_count":14},{"cell_type":"code","source":"from torchvision import datasets\nfrom torchvision.transforms import ToTensor, Resize, Compose, ConvertImageDtype, Normalize\n\n\nfrom pathlib import Path\n\nDATA_DIR = Path(\"/kaggle/input/10-monkey-species/\")\n\nclass MonkeyDataset(datasets.ImageFolder):\n    def __init__(self, mode, transform=None):\n        if mode == \"train\":\n            root = DATA_DIR / \"training/training\"\n        elif mode == \"val\":\n            root = DATA_DIR / \"validation/validation\"\n        else:\n            raise ValueError(\"mode should be one of the following: train, val, but got {}\".format(mode))\n        super().__init__(root, transform) # 调用父类init方法\n        # self.imgs = self.samples # self.samples里边是图片路径及标签 [(path, label), (path, label),...]\n        self.targets = [s[1] for s in self.samples] # 标签取出来\n\n# 预先设定的图片尺寸\nimg_h, img_w = 128, 128\ntransform = Compose([\n    Resize((img_h, img_w)), # 图片缩放\n    ToTensor(),\n    # 预先统计的\n    Normalize([0.4363, 0.4328, 0.3291], [0.2085, 0.2032, 0.1988]),\n    ConvertImageDtype(torch.float), # 转换为float类型\n]) #数据预处理\n\n\ntrain_ds = MonkeyDataset(\"train\", transform=transform)\nval_ds = MonkeyDataset(\"val\", transform=transform)\n\nprint(\"load {} images from training dataset\".format(len(train_ds)))\nprint(\"load {} images from validation dataset\".format(len(val_ds)))","metadata":{"ExecuteTime":{"end_time":"2025-01-20T06:11:16.093193Z","start_time":"2025-01-20T06:11:16.085329Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:29.859088Z","iopub.execute_input":"2025-01-20T06:36:29.859428Z","iopub.status.idle":"2025-01-20T06:36:30.358353Z","shell.execute_reply.started":"2025-01-20T06:36:29.859397Z","shell.execute_reply":"2025-01-20T06:36:30.357228Z"}},"outputs":[{"name":"stdout","text":"load 1097 images from training dataset\nload 272 images from validation dataset\n","output_type":"stream"}],"execution_count":15},{"cell_type":"code","source":"# 数据类别\ntrain_ds.classes","metadata":{"ExecuteTime":{"end_time":"2025-01-20T03:20:56.806185Z","start_time":"2025-01-20T03:20:56.802293Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.359296Z","iopub.execute_input":"2025-01-20T06:36:30.359660Z","iopub.status.idle":"2025-01-20T06:36:30.365146Z","shell.execute_reply.started":"2025-01-20T06:36:30.359589Z","shell.execute_reply":"2025-01-20T06:36:30.364178Z"}},"outputs":[{"execution_count":16,"output_type":"execute_result","data":{"text/plain":"['n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9']"},"metadata":{}}],"execution_count":16},{"cell_type":"code","source":"train_ds.class_to_idx","metadata":{"collapsed":false,"ExecuteTime":{"end_time":"2025-01-20T03:21:20.705210Z","start_time":"2025-01-20T03:21:20.702052Z"},"jupyter":{"outputs_hidden":false},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.366133Z","iopub.execute_input":"2025-01-20T06:36:30.366372Z","iopub.status.idle":"2025-01-20T06:36:30.382847Z","shell.execute_reply.started":"2025-01-20T06:36:30.366351Z","shell.execute_reply":"2025-01-20T06:36:30.382061Z"}},"outputs":[{"execution_count":17,"output_type":"execute_result","data":{"text/plain":"{'n0': 0,\n 'n1': 1,\n 'n2': 2,\n 'n3': 3,\n 'n4': 4,\n 'n5': 5,\n 'n6': 6,\n 'n7': 7,\n 'n8': 8,\n 'n9': 9}"},"metadata":{}}],"execution_count":17},{"cell_type":"code","source":"# # 图片路径 及 标签\ni=0\nfor fpath, label in train_ds.samples:\n    print(fpath, label)\n    i += 1\n    if i == 10:\n        break\n#\n# #这个和之前的dataset完全一致\n# for img, label in train_ds:\n#     # c, h, w  label\n#     print(img, label)\n#     break","metadata":{"ExecuteTime":{"end_time":"2025-01-20T06:12:12.952845Z","start_time":"2025-01-20T06:12:12.950468Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.385486Z","iopub.execute_input":"2025-01-20T06:36:30.385724Z","iopub.status.idle":"2025-01-20T06:36:30.402036Z","shell.execute_reply.started":"2025-01-20T06:36:30.385704Z","shell.execute_reply":"2025-01-20T06:36:30.401224Z"}},"outputs":[{"name":"stdout","text":"/kaggle/input/10-monkey-species/training/training/n0/n0018.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0019.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0020.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0021.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0022.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0023.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0024.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0025.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0026.jpg 0\n/kaggle/input/10-monkey-species/training/training/n0/n0027.jpg 0\n","output_type":"stream"}],"execution_count":18},{"cell_type":"code","source":"#因为有3通道，所有有3个mean和std\ndef cal_mean_std(ds):\n    mean = 0.\n    std = 0.\n    for img, _ in ds:\n        mean += img[:, :, :].mean(dim=(1, 2))\n        std += img[:, :, :].std(dim=(1, 2))\n    mean /= len(ds)\n    std /= len(ds)\n    return mean, std\n\n# 经过 normalize 后 均值为0，方差为1\n# print(cal_mean_std(train_ds))","metadata":{"collapsed":false,"ExecuteTime":{"end_time":"2025-01-20T06:09:13.418055Z","start_time":"2025-01-20T06:09:03.142747Z"},"jupyter":{"outputs_hidden":false},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.403437Z","iopub.execute_input":"2025-01-20T06:36:30.403700Z","iopub.status.idle":"2025-01-20T06:36:30.417624Z","shell.execute_reply.started":"2025-01-20T06:36:30.403680Z","shell.execute_reply":"2025-01-20T06:36:30.416756Z"}},"outputs":[],"execution_count":19},{"cell_type":"code","source":"# def cal_mean_std(ds):\n#     mean = 0.\n#     std = 0.\n#     for img, _ in ds:\n#         mean += img[1:2, :, :].mean(dim=(1, 2))\n#         std += img[1:2, :, :].std(dim=(1, 2))\n#     mean /= len(ds)\n#     std /= len(ds)\n#     return mean, std\n#\n# # 经过 normalize 后 均值为0，方差为1\n# print(cal_mean_std(train_ds))","metadata":{"collapsed":false,"ExecuteTime":{"end_time":"2024-07-24T10:45:25.811941100Z","start_time":"2024-07-24T10:45:25.787397500Z"},"jupyter":{"outputs_hidden":false},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.418487Z","iopub.execute_input":"2025-01-20T06:36:30.418803Z","iopub.status.idle":"2025-01-20T06:36:30.435635Z","shell.execute_reply.started":"2025-01-20T06:36:30.418775Z","shell.execute_reply":"2025-01-20T06:36:30.434767Z"}},"outputs":[],"execution_count":20},{"cell_type":"code","source":"def cal_mean_std(ds):\n    mean = 0.\n    std = 0.\n    for img, _ in ds:\n        mean += img[2:3, :, :].mean(dim=(1, 2))\n        std += img[2:3, :, :].std(dim=(1, 2))\n    mean /= len(ds)\n    std /= len(ds)\n    return mean, std\n\n# 经过 normalize 后 均值为0，方差为1\n# print(cal_mean_std(train_ds))","metadata":{"collapsed":false,"ExecuteTime":{"end_time":"2024-07-24T10:45:25.811941100Z","start_time":"2024-07-24T10:45:25.798389700Z"},"jupyter":{"outputs_hidden":false},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.436600Z","iopub.execute_input":"2025-01-20T06:36:30.436919Z","iopub.status.idle":"2025-01-20T06:36:30.453064Z","shell.execute_reply.started":"2025-01-20T06:36:30.436895Z","shell.execute_reply":"2025-01-20T06:36:30.452237Z"}},"outputs":[],"execution_count":21},{"cell_type":"code","source":"# 遍历train_ds得到每张图片，计算每个通道的均值和方差\ndef cal_mean_std(ds):\n    mean = 0.\n    std = 0.\n    for img, _ in ds:\n        mean += img.mean(dim=(1, 2)) #dim=(1, 2)表示计算均值后，宽和高消除（把宽和高所有的像素加起来，再除以总数）\n        std += img.std(dim=(1, 2))\n    mean /= len(ds)\n    std /= len(ds)\n    return mean, std\n\n# 经过 normalize 后 均值为0，方差为1\n# print(cal_mean_std(train_ds))","metadata":{"ExecuteTime":{"end_time":"2024-07-24T10:45:25.853621500Z","start_time":"2024-07-24T10:45:25.810941Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.453855Z","iopub.execute_input":"2025-01-20T06:36:30.454147Z","iopub.status.idle":"2025-01-20T06:36:30.466569Z","shell.execute_reply.started":"2025-01-20T06:36:30.454114Z","shell.execute_reply":"2025-01-20T06:36:30.465666Z"}},"outputs":[],"execution_count":22},{"cell_type":"code","source":"import torch.nn as nn\nfrom torch.utils.data.dataloader import DataLoader    \n\nbatch_size = 64\n# 从数据集到dataloader，num_workers参数不能加，否则会报错\n# https://github.com/pytorch/pytorch/issues/59438\ntrain_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\nval_loader = DataLoader(val_ds, batch_size=batch_size, shuffle=False)","metadata":{"ExecuteTime":{"end_time":"2025-01-20T06:16:46.736664Z","start_time":"2025-01-20T06:16:46.732486Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.467497Z","iopub.execute_input":"2025-01-20T06:36:30.467806Z","iopub.status.idle":"2025-01-20T06:36:30.480239Z","shell.execute_reply.started":"2025-01-20T06:36:30.467777Z","shell.execute_reply":"2025-01-20T06:36:30.479412Z"}},"outputs":[],"execution_count":23},{"cell_type":"code","source":"for imgs, labels in train_loader:\n    print(imgs.shape)\n    print(labels.shape)\n    break","metadata":{"ExecuteTime":{"end_time":"2025-01-20T06:16:51.114643Z","start_time":"2025-01-20T06:16:50.416683Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:30.481107Z","iopub.execute_input":"2025-01-20T06:36:30.481306Z","iopub.status.idle":"2025-01-20T06:36:32.372252Z","shell.execute_reply.started":"2025-01-20T06:36:30.481289Z","shell.execute_reply":"2025-01-20T06:36:32.371442Z"}},"outputs":[{"name":"stdout","text":"torch.Size([64, 3, 128, 128])\ntorch.Size([64])\n","output_type":"stream"}],"execution_count":24},{"cell_type":"markdown","source":"## 定义模型","metadata":{},"attachments":{}},{"cell_type":"code","source":"\nclass CNN(nn.Module):\n    def __init__(self, num_classes=10, activation=\"relu\"):\n        super(CNN, self).__init__()\n        self.activation = F.relu if activation == \"relu\" else F.selu\n        self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=\"same\")\n        self.conv2 = nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, padding=\"same\")\n        self.pool = nn.MaxPool2d(2, 2)\n        self.conv3 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=\"same\")\n        self.conv4 = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding=\"same\")\n        self.conv5 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=\"same\")\n        self.conv6 = nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, padding=\"same\")\n        self.flatten = nn.Flatten()\n        # input shape is (3, 128, 128) so the flatten output shape is 128 * 16 * 16\n        self.fc1 = nn.Linear(128 * 16 * 16, 128)\n        self.fc2 = nn.Linear(128, num_classes)\n        \n        self.init_weights()\n        \n    def init_weights(self):\n        \"\"\"使用 xavier 均匀分布来初始化全连接层、卷积层的权重 W\"\"\"\n        for m in self.modules():\n            if isinstance(m, (nn.Linear, nn.Conv2d)):\n                nn.init.xavier_uniform_(m.weight)\n                nn.init.zeros_(m.bias)\n        \n    def forward(self, x):\n        act = self.activation\n        x = self.pool(act(self.conv2(act(self.conv1(x)))))\n        x = self.pool(act(self.conv4(act(self.conv3(x)))))\n        x = self.pool(act(self.conv6(act(self.conv5(x)))))\n        x = self.flatten(x)\n        x = act(self.fc1(x))\n        x = self.fc2(x)\n        return x\n    \n\nfor idx, (key, value) in enumerate(CNN().named_parameters()):\n    print(f\"{key}\\tparamerters num: {np.prod(value.shape)}\")\n","metadata":{"ExecuteTime":{"end_time":"2025-01-20T06:17:56.482409Z","start_time":"2025-01-20T06:17:56.448767Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:32.373171Z","iopub.execute_input":"2025-01-20T06:36:32.373531Z","iopub.status.idle":"2025-01-20T06:36:32.455265Z","shell.execute_reply.started":"2025-01-20T06:36:32.373496Z","shell.execute_reply":"2025-01-20T06:36:32.454510Z"}},"outputs":[{"name":"stdout","text":"conv1.weight\tparamerters num: 864\nconv1.bias\tparamerters num: 32\nconv2.weight\tparamerters num: 9216\nconv2.bias\tparamerters num: 32\nconv3.weight\tparamerters num: 18432\nconv3.bias\tparamerters num: 64\nconv4.weight\tparamerters num: 36864\nconv4.bias\tparamerters num: 64\nconv5.weight\tparamerters num: 73728\nconv5.bias\tparamerters num: 128\nconv6.weight\tparamerters num: 147456\nconv6.bias\tparamerters num: 128\nfc1.weight\tparamerters num: 4194304\nfc1.bias\tparamerters num: 128\nfc2.weight\tparamerters num: 1280\nfc2.bias\tparamerters num: 10\n","output_type":"stream"}],"execution_count":25},{"cell_type":"code","source":"def count_parameters(model): #计算模型总参数量\n    return sum(p.numel() for p in model.parameters() if p.requires_grad)\ncount_parameters(CNN())","metadata":{"ExecuteTime":{"end_time":"2025-01-20T06:18:23.876602Z","start_time":"2025-01-20T06:18:23.849452Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:32.456074Z","iopub.execute_input":"2025-01-20T06:36:32.456374Z","iopub.status.idle":"2025-01-20T06:36:32.528727Z","shell.execute_reply.started":"2025-01-20T06:36:32.456352Z","shell.execute_reply":"2025-01-20T06:36:32.527789Z"}},"outputs":[{"execution_count":26,"output_type":"execute_result","data":{"text/plain":"4482730"},"metadata":{}}],"execution_count":26},{"cell_type":"code","source":"128*16*16*128","metadata":{"ExecuteTime":{"end_time":"2025-01-20T06:21:44.093149Z","start_time":"2025-01-20T06:21:44.089427Z"},"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:32.529484Z","iopub.execute_input":"2025-01-20T06:36:32.529750Z","iopub.status.idle":"2025-01-20T06:36:32.534369Z","shell.execute_reply.started":"2025-01-20T06:36:32.529730Z","shell.execute_reply":"2025-01-20T06:36:32.533615Z"}},"outputs":[{"execution_count":27,"output_type":"execute_result","data":{"text/plain":"4194304"},"metadata":{}}],"execution_count":27},{"cell_type":"markdown","source":"## 训练\n\npytorch的训练需要自行实现，包括\n1. 定义损失函数\n2. 定义优化器\n3. 定义训练步\n4. 训练","metadata":{},"attachments":{}},{"cell_type":"code","source":"from sklearn.metrics import accuracy_score\n\n@torch.no_grad()\ndef evaluating(model, dataloader, loss_fct):\n    loss_list = []\n    pred_list = []\n    label_list = []\n    for datas, labels in dataloader:\n        datas = datas.to(device)\n        labels = labels.to(device)\n        # 前向计算\n        logits = model(datas)\n        loss = loss_fct(logits, labels)         # 验证集损失\n        loss_list.append(loss.item())\n        \n        preds = logits.argmax(axis=-1)    # 验证集预测\n        pred_list.extend(preds.cpu().numpy().tolist())\n        label_list.extend(labels.cpu().numpy().tolist())\n        \n    acc = accuracy_score(label_list, pred_list)\n    return np.mean(loss_list), acc\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:32.535345Z","iopub.execute_input":"2025-01-20T06:36:32.535659Z","iopub.status.idle":"2025-01-20T06:36:32.649228Z","shell.execute_reply.started":"2025-01-20T06:36:32.535627Z","shell.execute_reply":"2025-01-20T06:36:32.648525Z"}},"outputs":[],"execution_count":28},{"cell_type":"markdown","source":"### TensorBoard 可视化\n\n\n训练过程中可以使用如下命令启动tensorboard服务。\n\n```shell\ntensorboard \\\n    --logdir=runs \\     # log 存放路径\n    --host 0.0.0.0 \\    # ip\n    --port 8848         # 端口\n```","metadata":{},"attachments":{}},{"cell_type":"code","source":"from torch.utils.tensorboard import SummaryWriter\n\n\nclass TensorBoardCallback:\n    def __init__(self, log_dir, flush_secs=10):\n        \"\"\"\n        Args:\n            log_dir (str): dir to write log.\n            flush_secs (int, optional): write to dsk each flush_secs seconds. Defaults to 10.\n        \"\"\"\n        self.writer = SummaryWriter(log_dir=log_dir, flush_secs=flush_secs)\n\n    def draw_model(self, model, input_shape):\n        self.writer.add_graph(model, input_to_model=torch.randn(input_shape))\n        \n    def add_loss_scalars(self, step, loss, val_loss):\n        self.writer.add_scalars(\n            main_tag=\"training/loss\", \n            tag_scalar_dict={\"loss\": loss, \"val_loss\": val_loss},\n            global_step=step,\n            )\n        \n    def add_acc_scalars(self, step, acc, val_acc):\n        self.writer.add_scalars(\n            main_tag=\"training/accuracy\",\n            tag_scalar_dict={\"accuracy\": acc, \"val_accuracy\": val_acc},\n            global_step=step,\n        )\n        \n    def add_lr_scalars(self, step, learning_rate):\n        self.writer.add_scalars(\n            main_tag=\"training/learning_rate\",\n            tag_scalar_dict={\"learning_rate\": learning_rate},\n            global_step=step,\n            \n        )\n    \n    def __call__(self, step, **kwargs):\n        # add loss\n        loss = kwargs.pop(\"loss\", None)\n        val_loss = kwargs.pop(\"val_loss\", None)\n        if loss is not None and val_loss is not None:\n            self.add_loss_scalars(step, loss, val_loss)\n        # add acc\n        acc = kwargs.pop(\"acc\", None)\n        val_acc = kwargs.pop(\"val_acc\", None)\n        if acc is not None and val_acc is not None:\n            self.add_acc_scalars(step, acc, val_acc)\n        # add lr\n        learning_rate = kwargs.pop(\"lr\", None)\n        if learning_rate is not None:\n            self.add_lr_scalars(step, learning_rate)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:32.650049Z","iopub.execute_input":"2025-01-20T06:36:32.650275Z","iopub.status.idle":"2025-01-20T06:36:45.032061Z","shell.execute_reply.started":"2025-01-20T06:36:32.650257Z","shell.execute_reply":"2025-01-20T06:36:45.031156Z"}},"outputs":[],"execution_count":29},{"cell_type":"markdown","source":"### Save Best\n","metadata":{},"attachments":{}},{"cell_type":"code","source":"class SaveCheckpointsCallback:\n    def __init__(self, save_dir, save_step=5000, save_best_only=True):\n        \"\"\"\n        Save checkpoints each save_epoch epoch. \n        We save checkpoint by epoch in this implementation.\n        Usually, training scripts with pytorch evaluating model and save checkpoint by step.\n\n        Args:\n            save_dir (str): dir to save checkpoint\n            save_epoch (int, optional): the frequency to save checkpoint. Defaults to 1.\n            save_best_only (bool, optional): If True, only save the best model or save each model at every epoch.\n        \"\"\"\n        self.save_dir = save_dir\n        self.save_step = save_step\n        self.save_best_only = save_best_only\n        self.best_metrics = -1\n        \n        # mkdir\n        if not os.path.exists(self.save_dir):\n            os.mkdir(self.save_dir)\n        \n    def __call__(self, step, state_dict, metric=None):\n        if step % self.save_step > 0:\n            return\n        \n        if self.save_best_only:\n            assert metric is not None\n            if metric >= self.best_metrics:\n                # save checkpoints\n                torch.save(state_dict, os.path.join(self.save_dir, \"best.ckpt\"))\n                # update best metrics\n                self.best_metrics = metric\n        else:\n            torch.save(state_dict, os.path.join(self.save_dir, f\"{step}.ckpt\"))\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:45.032943Z","iopub.execute_input":"2025-01-20T06:36:45.033484Z","iopub.status.idle":"2025-01-20T06:36:45.039021Z","shell.execute_reply.started":"2025-01-20T06:36:45.033461Z","shell.execute_reply":"2025-01-20T06:36:45.038130Z"}},"outputs":[],"execution_count":30},{"cell_type":"markdown","source":"### Early Stop","metadata":{},"attachments":{}},{"cell_type":"code","source":"class EarlyStopCallback:\n    def __init__(self, patience=5, min_delta=0.01):\n        \"\"\"\n\n        Args:\n            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n        \"\"\"\n        self.patience = patience\n        self.min_delta = min_delta\n        self.best_metric = -1\n        self.counter = 0\n        \n    def __call__(self, metric):\n        if metric >= self.best_metric + self.min_delta:\n            # update best metric\n            self.best_metric = metric\n            # reset counter \n            self.counter = 0\n        else: \n            self.counter += 1\n            \n    @property\n    def early_stop(self):\n        return self.counter >= self.patience\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:45.040018Z","iopub.execute_input":"2025-01-20T06:36:45.040336Z","iopub.status.idle":"2025-01-20T06:36:45.074390Z","shell.execute_reply.started":"2025-01-20T06:36:45.040291Z","shell.execute_reply":"2025-01-20T06:36:45.073709Z"}},"outputs":[],"execution_count":31},{"cell_type":"code","source":"# 训练\ndef training(\n    model, \n    train_loader, \n    val_loader, \n    epoch, \n    loss_fct, \n    optimizer, \n    tensorboard_callback=None,\n    save_ckpt_callback=None,\n    early_stop_callback=None,\n    eval_step=500,\n    ):\n    record_dict = {\n        \"train\": [],\n        \"val\": []\n    }\n    \n    global_step = 0\n    model.train()\n    with tqdm(total=epoch * len(train_loader)) as pbar:\n        for epoch_id in range(epoch):\n            # training\n            for datas, labels in train_loader:\n                datas = datas.to(device)\n                labels = labels.to(device)\n                # 梯度清空\n                optimizer.zero_grad()\n                # 模型前向计算\n                logits = model(datas)\n                # 计算损失\n                loss = loss_fct(logits, labels)\n                # 梯度回传\n                loss.backward()\n                # 调整优化器，包括学习率的变动等\n                optimizer.step()\n                preds = logits.argmax(axis=-1)\n            \n                acc = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())    \n                loss = loss.cpu().item()\n                # record\n                \n                record_dict[\"train\"].append({\n                    \"loss\": loss, \"acc\": acc, \"step\": global_step\n                })\n                \n                # evaluating\n                if global_step % eval_step == 0:\n                    model.eval()\n                    val_loss, val_acc = evaluating(model, val_loader, loss_fct)\n                    record_dict[\"val\"].append({\n                        \"loss\": val_loss, \"acc\": val_acc, \"step\": global_step\n                    })\n                    model.train()\n                    \n                    # 1. 使用 tensorboard 可视化\n                    if tensorboard_callback is not None:\n                        tensorboard_callback(\n                            global_step, \n                            loss=loss, val_loss=val_loss,\n                            acc=acc, val_acc=val_acc,\n                            lr=optimizer.param_groups[0][\"lr\"],\n                            )\n                \n                    # 2. 保存模型权重 save model checkpoint\n                    if save_ckpt_callback is not None:\n                        save_ckpt_callback(global_step, model.state_dict(), metric=val_acc)\n\n                    # 3. 早停 Early Stop\n                    if early_stop_callback is not None:\n                        early_stop_callback(val_acc)\n                        if early_stop_callback.early_stop:\n                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n                            return record_dict\n                    \n                # udate step\n                global_step += 1\n                pbar.update(1)\n                pbar.set_postfix({\"epoch\": epoch_id})\n        \n    return record_dict\n        \n\nepoch = 20\n\nactivation = \"relu\"\nmodel = CNN(num_classes=10, activation=activation)\n\n# 1. 定义损失函数 采用交叉熵损失\nloss_fct = nn.CrossEntropyLoss()\n# 2. 定义优化器 采用 adam\n# Optimizers specified in the torch.optim package\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001, eps=1e-7)\n\n# 1. tensorboard 可视化\nif not os.path.exists(\"runs\"):\n    os.mkdir(\"runs\")\ntensorboard_callback = TensorBoardCallback(f\"runs/monkeys-cnn-{activation}\")\ntensorboard_callback.draw_model(model, [1, 3, img_h, img_w])\n# 2. save best\nif not os.path.exists(\"checkpoints\"):\n    os.makedirs(\"checkpoints\")\nsave_ckpt_callback = SaveCheckpointsCallback(f\"checkpoints/monkeys-cnn-{activation}\", save_step=len(train_loader), save_best_only=True)\n# 3. early stop\nearly_stop_callback = EarlyStopCallback(patience=5)\n\nmodel = model.to(device)\nrecord = training(\n    model, \n    train_loader, \n    val_loader, \n    epoch, \n    loss_fct, \n    optimizer, \n    tensorboard_callback=tensorboard_callback,\n    save_ckpt_callback=save_ckpt_callback,\n    early_stop_callback=early_stop_callback,\n    eval_step=len(train_loader)\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:36:45.075320Z","iopub.execute_input":"2025-01-20T06:36:45.075619Z","iopub.status.idle":"2025-01-20T06:44:35.888183Z","shell.execute_reply.started":"2025-01-20T06:36:45.075590Z","shell.execute_reply":"2025-01-20T06:44:35.887309Z"}},"outputs":[{"output_type":"display_data","data":{"text/plain":"  0%|          | 0/360 [00:00<?, ?it/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"b57e1fa86d054fe6a4349b2116c5fd7e"}},"metadata":{}},{"name":"stdout","text":"Early stop at epoch 16 / global_step 288\n","output_type":"stream"}],"execution_count":32},{"cell_type":"code","source":"#画线要注意的是损失是不一定在零到1之间的\ndef plot_learning_curves(record_dict, sample_step=500):\n    # build DataFrame\n    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n\n    # plot\n    fig_num = len(train_df.columns)\n    fig, axs = plt.subplots(1, fig_num, figsize=(5 * fig_num, 5))\n    for idx, item in enumerate(train_df.columns):    \n        axs[idx].plot(train_df.index, train_df[item], label=f\"train_{item}\")\n        axs[idx].plot(val_df.index, val_df[item], label=f\"val_{item}\")\n        axs[idx].grid()\n        axs[idx].legend()\n        # axs[idx].set_xticks(range(0, train_df.index[-1], 5000))\n        # axs[idx].set_xticklabels(map(lambda x: f\"{int(x/1000)}k\", range(0, train_df.index[-1], 5000)))\n        axs[idx].set_xlabel(\"step\")\n    \n    plt.show()\n\nplot_learning_curves(record, sample_step=10)  #横坐标是 steps","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:44:35.890889Z","iopub.execute_input":"2025-01-20T06:44:35.891149Z","iopub.status.idle":"2025-01-20T06:44:36.216190Z","shell.execute_reply.started":"2025-01-20T06:44:35.891127Z","shell.execute_reply":"2025-01-20T06:44:36.215280Z"}},"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 1000x500 with 2 Axes>","image/png":"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WIRby8/PZ9euXezatQtQykDv2rWrrKd79uzZTJkypez506dP5/jx4zz++OMcOnSI999/n++++45HH33UFeG7FXe9Nq1fv57+/fvzwAMP0L17d+Li4khKSip7PCgoiNjYWFatWlXp/l26dOH06dMcOXLEaTGKil75/RBpuSXEhvnz0FBl2GNEsC9f33MFzUL9OJ5ZwO2fbSa7sPrEuDaKDGbu+mIbu09l08hfx1d39aVVePlEXatRM6FXDH88djVzrutIeKCelKxCHvl2F6PfXsuK/alePW/4aFoe0xds57p317P2aCY6jYop/Vqy5p+D+deodg0quQE378HxFLGxsWzevJnk5GQCAwOr/AYrPj6en376ibFjx6JSqXj66aed0hNTlX/84x/07t2bF154gYkTJ7Jx40beffdd3n//fQB+/fVXjh8/zsCBA2nUqBHLli3DYrHQtm1bNm/ezKpVqxgxYgQRERFs3ryZjIwM2rdvX2/xCw92/hhYLumCzq5+WKZouLZt28bgwYPLbtvmykydOpX58+dz7ty5csN6W7VqxdKlS3n00Ud5++23ad68OZ9++qmUiMZ9r03x8fF8+eWXLF++nFatWrFgwQK2bt1abjTAc889x/Tp04mIiGDUqFHk5eWxfv16HnzwQa6++moGDhzIjTfeyBtvvEFcXByHDh1CpVLZPTfV2z3x0z42HNLQoW8B8VGhtT7OtuQsvtqk/N29fEPncvNbmoX68fXdfZnw0UYOpeYxdd4Wvrq7L0G+jhnuV2Iyc99X29lyIosgvZYv7+xb7fwRvVbD1P6xTOjVnM/XJ/PRX0kcTsvj3gXbGdUpivcn97BrmKe7O5VVyFsrj7J452ksVlCpYHz3Zjw6LIGYepoX5Y6kB8cBHnvsMTQaDR06dKBJkyZVzql54403aNSoEf3792fs2LGMHDmSHj161FucPXr04LvvvmPRokV06tSJZ555hueff55p06YBEBoayk8//cSQIUNo3749H374Id988w0dO3YkODiYNWvWMHr0aBISEnjqqad4/fXX7VqvQjRgtvk3NjmS4IjKDRo0CKvVWuFn/vz5AMyfP5/Vq1dX2Gfnzp2UlJSQlJRU9p7W0Lnrtem+++7jhhtuYOLEifTt25fz58/zwAMPlHvO1KlTeeutt3j//ffp2LEjY8aM4ejRi73AP/74I717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\n"},"metadata":{}}],"execution_count":33},{"cell_type":"markdown","source":"# 评估","metadata":{},"attachments":{}},{"cell_type":"code","source":"# dataload for evaluating\n\n# load checkpoints\nmodel.load_state_dict(torch.load(f\"checkpoints/monkeys-cnn-{activation}/best.ckpt\", map_location=\"cpu\"))\n\nmodel.eval()\nloss, acc = evaluating(model, val_loader, loss_fct)\nprint(f\"loss:     {loss:.4f}\\naccuracy: {acc:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-20T06:44:36.217046Z","iopub.execute_input":"2025-01-20T06:44:36.217268Z","iopub.status.idle":"2025-01-20T06:44:42.178774Z","shell.execute_reply.started":"2025-01-20T06:44:36.217249Z","shell.execute_reply":"2025-01-20T06:44:42.177896Z"}},"outputs":[{"name":"stderr","text":"<ipython-input-34-5cfd5a3971ab>:4: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n  model.load_state_dict(torch.load(f\"checkpoints/monkeys-cnn-{activation}/best.ckpt\", map_location=\"cpu\"))\n","output_type":"stream"},{"name":"stdout","text":"loss:     3.2841\naccuracy: 0.5993\n","output_type":"stream"}],"execution_count":34}]}